﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Primitives;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Nop.Core;
using Nop.Core.Caching;
using Nop.Core.Configuration;
using Nop.Core.Domain;
using Nop.Core.Domain.Catalog;
using Nop.Core.Domain.Common;
using Nop.Core.Domain.Customers;
using Nop.Core.Domain.Forums;
using Nop.Core.Domain.Gdpr;
using Nop.Core.Domain.Localization;
using Nop.Core.Domain.Media;
using Nop.Core.Domain.Messages;
using Nop.Core.Domain.Security;
using Nop.Core.Domain.Tax;
using Nop.Services.Authentication;
using Nop.Services.Authentication.External;
using Nop.Services.Catalog;
using Nop.Services.Common;
using Nop.Services.Customers;
using Nop.Services.Directory;
using Nop.Services.Events;
using Nop.Services.ExportImport;
using Nop.Services.Gdpr;
using Nop.Services.Helpers;
using Nop.Services.Localization;
using Nop.Services.Logging;
using Nop.Services.Media;
using Nop.Services.Messages;
using Nop.Services.Orders;
using Nop.Services.Tax;
using Nop.Web.Areas.App.Models;
using Nop.Web.Areas.App.Models.Member;
using Nop.Web.Extensions;
using Nop.Web.Factories;
using Nop.Web.Framework;
using Nop.Web.Framework.Controllers;
using Nop.Web.Framework.Mvc.Filters;
using Nop.Web.Framework.Security;
using Nop.Web.Framework.Security.Captcha;
using Nop.Web.Framework.Validators;
using Nop.Web.Models.Common;
using Nop.Web.Models.Customer;
using Nop.Web.Services.Easemob;
using Nop.Web.Services.Factories;
using Nop.Web.Services.Utils;
using PayCenter.Sdk.Models;

namespace Nop.Web.Areas.App.Controllers
{
    public class CustomerController : BaseAppController
    {
        #region Fields
        private readonly HUCFactory _hUCFactory;
        private readonly HUCSdkHelper _hUCSdkHelper;
        private readonly AddressSettings _addressSettings;
        private readonly CaptchaSettings _captchaSettings;
        private readonly CustomerSettings _customerSettings;
        private readonly DateTimeSettings _dateTimeSettings;
        private readonly IDownloadService _downloadService;
        private readonly ForumSettings _forumSettings;
        private readonly GdprSettings _gdprSettings;
        private readonly IAddressAttributeParser _addressAttributeParser;
        private readonly IAddressModelFactory _addressModelFactory;
        private readonly IAddressService _addressService;
        private readonly IAuthenticationService _authenticationService;
        private readonly ICountryService _countryService;
        private readonly ICurrencyService _currencyService;
        private readonly ICustomerActivityService _customerActivityService;
        private readonly ICustomerAttributeParser _customerAttributeParser;
        private readonly ICustomerAttributeService _customerAttributeService;
        private readonly ICustomerModelFactory _customerModelFactory;
        private readonly ICustomerRegistrationService _customerRegistrationService;
        private readonly ICustomerService _customerService;
        private readonly IEventPublisher _eventPublisher;
        private readonly IExportManager _exportManager;
        private readonly IExternalAuthenticationService _externalAuthenticationService;
        private readonly IGdprService _gdprService;
        private readonly IGenericAttributeService _genericAttributeService;
        private readonly IGiftCardService _giftCardService;
        private readonly ILocalizationService _localizationService;
        private readonly INewsLetterSubscriptionService _newsLetterSubscriptionService;
        private readonly IOrderService _orderService;
        private readonly IPictureService _pictureService;
        private readonly IPriceFormatter _priceFormatter;
        private readonly IShoppingCartService _shoppingCartService;
        private readonly IStoreContext _storeContext;
        private readonly ITaxService _taxService;
        private readonly IWebHelper _webHelper;
        private readonly IWorkContext _workContext;
        private readonly IWorkflowMessageService _workflowMessageService;
        private readonly LocalizationSettings _localizationSettings;
        private readonly MediaSettings _mediaSettings;
        private readonly StoreInformationSettings _storeInformationSettings;
        private readonly TaxSettings _taxSettings;
        private readonly NopConfig _config;
        private readonly IProductService _productService;
        private readonly HPaySdkHelper _paySdkHelper;
        private readonly EasemobManager _easemobManager;
        private readonly IStaticCacheManager _cacheManager;
        #endregion

        #region Ctor

        public CustomerController(
            HPaySdkHelper paySdkHelper,
            AddressSettings addressSettings,
            CaptchaSettings captchaSettings,
            CustomerSettings customerSettings,
            DateTimeSettings dateTimeSettings,
            IDownloadService downloadService,
            ForumSettings forumSettings,
            GdprSettings gdprSettings,
            IAddressAttributeParser addressAttributeParser,
            IAddressModelFactory addressModelFactory,
            IAddressService addressService,
            IAuthenticationService authenticationService,
            ICountryService countryService,
            ICurrencyService currencyService,
            ICustomerActivityService customerActivityService,
            ICustomerAttributeParser customerAttributeParser,
            ICustomerAttributeService customerAttributeService,
            ICustomerModelFactory customerModelFactory,
            ICustomerRegistrationService customerRegistrationService,
            ICustomerService customerService,
            IEventPublisher eventPublisher,
            IExportManager exportManager,
            IExternalAuthenticationService externalAuthenticationService,
            IGdprService gdprService,
            IGenericAttributeService genericAttributeService,
            IGiftCardService giftCardService,
            ILocalizationService localizationService,
            INewsLetterSubscriptionService newsLetterSubscriptionService,
            IOrderService orderService,
            IPictureService pictureService,
            IPriceFormatter priceFormatter,
            IShoppingCartService shoppingCartService,
            IStoreContext storeContext,
            ITaxService taxService,
            IWebHelper webHelper,
            IWorkContext workContext,
            IWorkflowMessageService workflowMessageService,
            LocalizationSettings localizationSettings,
            MediaSettings mediaSettings,
            StoreInformationSettings storeInformationSettings,
            TaxSettings taxSettings,
            NopConfig config, IProductService productService,
            EasemobManager easemobManager,
            IStaticCacheManager cacheManager,
             HUCFactory hUCFactory,
          HUCSdkHelper hUCSdkHelper
            )
        {
            this._paySdkHelper = paySdkHelper;
            this._addressSettings = addressSettings;
            this._captchaSettings = captchaSettings;
            this._customerSettings = customerSettings;
            this._dateTimeSettings = dateTimeSettings;
            this._downloadService = downloadService;
            this._forumSettings = forumSettings;
            this._gdprSettings = gdprSettings;
            this._addressAttributeParser = addressAttributeParser;
            this._addressModelFactory = addressModelFactory;
            this._addressService = addressService;
            this._authenticationService = authenticationService;
            this._countryService = countryService;
            this._currencyService = currencyService;
            this._customerActivityService = customerActivityService;
            this._customerAttributeParser = customerAttributeParser;
            this._customerAttributeService = customerAttributeService;
            this._customerModelFactory = customerModelFactory;
            this._customerRegistrationService = customerRegistrationService;
            this._customerService = customerService;
            this._eventPublisher = eventPublisher;
            this._exportManager = exportManager;
            this._externalAuthenticationService = externalAuthenticationService;
            this._gdprService = gdprService;
            this._genericAttributeService = genericAttributeService;
            this._giftCardService = giftCardService;
            this._localizationService = localizationService;
            this._newsLetterSubscriptionService = newsLetterSubscriptionService;
            this._orderService = orderService;
            this._pictureService = pictureService;
            this._priceFormatter = priceFormatter;
            this._shoppingCartService = shoppingCartService;
            this._storeContext = storeContext;
            this._taxService = taxService;
            this._webHelper = webHelper;
            this._workContext = workContext;
            this._workflowMessageService = workflowMessageService;
            this._localizationSettings = localizationSettings;
            this._mediaSettings = mediaSettings;
            this._storeInformationSettings = storeInformationSettings;
            this._taxSettings = taxSettings;
            this._config = config;
            this._productService = productService;
            this._easemobManager = easemobManager;
            this._cacheManager = cacheManager;
            this._hUCFactory = hUCFactory;
            this._hUCSdkHelper = hUCSdkHelper;
        }

        #endregion



        public virtual IActionResult Addresses()
        {
            if (!_workContext.CurrentCustomer.IsRegistered())
                return Json(new AppResult
                {
                    Code = 999,
                    Message = "您还没有登录"
                });

            var model = _customerModelFactory.PrepareCustomerAddressListModel(true);
            return Json(new AppResult
            {
                Result = model
            });
        }

        public virtual IActionResult AddressDelete(int addressId)
        {
            if (!_workContext.CurrentCustomer.IsRegistered())
                return Json(new AppResult
                {
                    Code = 999,
                    Message = "您还没有登录"
                });

            var customer = _workContext.CurrentCustomer;

            //find address (ensure that it belongs to the current customer)
            var address = customer.Addresses.FirstOrDefault(a => a.Id == addressId);
            if (address != null)
            {
                if (address.IsDefault)
                {
                    var defaultAddress = customer.Addresses.Where(a => a.Id != addressId).FirstOrDefault();
                    if (defaultAddress != null)
                    {
                        defaultAddress.IsDefault = true;
                        _addressService.UpdateAddress(defaultAddress);
                    }
                }
                _customerService.RemoveCustomerAddress(customer, address);
                _customerService.UpdateCustomer(customer);
                //now delete the address record
                _addressService.DeleteAddress(address);

            }

            return Json(new AppResult
            {

            });
        }

        public virtual IActionResult AddressAdd(AddressModel address)
        {
            if (!_workContext.CurrentCustomer.IsRegistered())
                return Json(new AppResult
                {
                    Code = 999,
                    Message = "您还没有登录"
                });

            var customer = _workContext.CurrentCustomer;

            var addressData = address.ToEntity();
            addressData.CreatedOnUtc = DateTime.UtcNow;

            if (addressData.CountryId == 0)
                addressData.CountryId = null;
            if (addressData.StateProvinceId == 0)
                addressData.StateProvinceId = null;

            customer.CustomerAddressMappings.Add(new CustomerAddressMapping { Address = addressData });
            _customerService.UpdateCustomer(customer);

            var defaultAddresses = customer.Addresses.Where(a => a.IsDefault);
            if (defaultAddresses.Count() > 1)
            {
                var needUnDefault = defaultAddresses.Where(a => a.Id != addressData.Id).SingleOrDefault();
                needUnDefault.IsDefault = false;
                _addressService.UpdateAddress(needUnDefault);
            }

            return Json(new AppResult
            {
                Result = addressData.Id
            });


        }

        public virtual IActionResult AddressEdit(AddressModel address)
        {
            if (!_workContext.CurrentCustomer.IsRegistered())
                return Json(new AppResult
                {
                    Code = 999,
                    Message = "您还没有登录"
                });

            int addressId = address.Id;
            var customer = _workContext.CurrentCustomer;
            //find address (ensure that it belongs to the current customer)
            var addressData = customer.Addresses.FirstOrDefault(a => a.Id == addressId);
            if (addressData == null)
                return Json(new AppResult
                {
                    Code = 500,
                    Message = "地址不存在"
                });

            addressData = address.ToEntity(addressData);
            _addressService.UpdateAddress(addressData);

            var defaultAddresses = customer.Addresses.Where(a => a.IsDefault);
            if (defaultAddresses.Count() > 1)
            {
                var needUnDefault = defaultAddresses.Where(a => a.Id != addressId).SingleOrDefault();
                needUnDefault.IsDefault = false;
                _addressService.UpdateAddress(needUnDefault);
            }
            if (defaultAddresses.Count() < 1)
            {
                var defaultAddress = customer.Addresses.Where(a => a.Id != addressId).FirstOrDefault();
                if (defaultAddress != null)
                {
                    defaultAddress.IsDefault = true;
                    _addressService.UpdateAddress(defaultAddress);
                }

            }

            return Json(new AppResult
            {

            });



        }


        public IActionResult Wallets()
        {
            if (!_workContext.CurrentCustomer.IsRegistered())
                return Json(new AppResult
                {
                    Code = 999,
                    Message = "您还没有登录"
                });

            var ucMemberId = _hUCSdkHelper.GetMemberId(_workContext.CurrentCustomer);
            if (ucMemberId < 1)
                return Json(new AppResult
                {
                    Code = 999,
                    Message = "您还没有登录"
                });

            var sdk = _paySdkHelper.Get();
            var walletTemplates = _productService.GetWalletTemplateList();
            List<WalletModel> walletList = new List<WalletModel>();
            foreach (var item in walletTemplates)
            {
                var walletResult = sdk.GetWallet(ucMemberId, item.WalletId).Result;
                if (!walletResult.Success)
                {

                    if (walletResult.Code == "8007")
                    {
                        var createResult = sdk.CreateWalletAsync(ucMemberId, item.WalletId, item.Name, item.IconUrl).Result;
                        if (!createResult.Success)
                        {
                            return Json(new AppResult
                            {
                                Code = 500,
                                Message = createResult.Message
                            });
                        }
                        else
                        {
                            walletList.Add(new WalletModel()
                            {
                                Balance = 0,
                                Name = item.Name,
                                IcoUrl = item.IconUrl,
                                WalletId = createResult.WalletId,
                                WalletType = item.WalletId
                            });
                        }
                    }
                    else
                    {
                        return Json(new AppResult
                        {
                            Code = 500,
                            Message = walletResult.Message
                        });
                    }
                }
                else
                {
                    walletList.Add(new WalletModel()
                    {
                        Balance = walletResult.Wallet.Balance,
                        Name = item.Name,
                        IcoUrl = item.IconUrl,
                        WalletId = walletResult.Wallet.WalletId,
                        WalletType = item.WalletId
                    });

                }

            }
            return Json(new AppResult
            {
                Result = new
                {
                    Wallets = walletList
                }
            });


        }

        public IActionResult WalletRecord(int walletType)
        {
            if (!_workContext.CurrentCustomer.IsRegistered())
                return Json(new AppResult
                {
                    Code = 999,
                    Message = "您还没有登录"
                });

            var ucMemberId = _hUCSdkHelper.GetMemberId(_workContext.CurrentCustomer);
            if (ucMemberId < 1)
                return Json(new AppResult
                {
                    Code = 999,
                    Message = "您还没有登录"
                });

            var sdk = _paySdkHelper.Get();
            var walletResult = sdk.GetWallet(ucMemberId, walletType).Result;
            if (!walletResult.Success)
            {
                return Json(new AppResult
                {
                    Code = 500,
                    Message = walletResult.Message
                });
            }
            var recordResult = sdk.WalletRecordList(walletResult.Wallet.WalletId).Result;
            if (!recordResult.Success)
            {
                return Json(new AppResult
                {
                    Code = 500,
                    Message = recordResult.Message
                });
            }
            return Json(new AppResult
            {
                Result = new
                {
                    Wallet = walletResult.Wallet,
                    Records = recordResult.Records
                }
            });
        }

        public IActionResult GetEasemobUser()
        {
            if (!_workContext.CurrentCustomer.IsRegistered())
                return Json(new AppResult
                {
                    Code = 999,
                    Message = "您还没有登录"
                });
            var ucMemberId = _hUCSdkHelper.GetMemberId(_workContext.CurrentCustomer);
            if (ucMemberId < 1)
                return Json(new AppResult
                {
                    Code = 999,
                    Message = "您还没有登录"
                });
            string easeUserName = string.Format("huc_{0}_nop_{1}", ucMemberId, _workContext.CurrentCustomer.Id);
            var user = _cacheManager.Get<EasemobUser>(easeUserName, () =>
              {
                  EasemobUser _user = new EasemobUser();
                  var json = _easemobManager.GetUser(easeUserName);
                  if (string.IsNullOrEmpty(json))
                  {
                      var registerResult = _easemobManager.RegisterUser(easeUserName, easeUserName);
                      var jObj = JsonConvert.DeserializeObject(registerResult) as JObject;
                      if (jObj.ContainsKey("entities"))
                      {
                          _user.Uuid = (jObj["entities"] as JArray).First["uuid"].ToString();
                      }

                  }
                  else
                  {
                      var jObj = JsonConvert.DeserializeObject(json) as JObject;
                      if (jObj.ContainsKey("entities"))
                      {
                          _user.Uuid = (jObj["entities"] as JArray).First["uuid"].ToString();
                      }
                  }
                  _user.Password = easeUserName;
                  _user.UserName = easeUserName;
                  return _user;
              });
            return Json(new AppResult
            {
                Result = user
            });
        }

        public IActionResult MyGroup()
        {
            if (!_workContext.CurrentCustomer.IsRegistered())
                return Json(new AppResult
                {
                    Code = 999,
                    Message = "您还没有登录"
                });

            var countInfo = _hUCFactory.ChildrenOrderCount(_workContext.CurrentCustomer, true);
            if (!countInfo.result)
            {
                return Json(new AppResult
                {
                    Code = 500,
                    Message = "用户中心数据获取失败,请重试"
                });
            }
            return Json(new AppResult
            {
                Result = new
                {
                    countInfo = countInfo.list
                }
            });
        }

        public IActionResult WalletTransfer(string phone, int amount, int walletType)
        {
            if (amount < 100)
            {
                return Json(new AppResult
                {
                    Code = 500,
                    Message = "转账金额最小为1"
                });
            }
            if (string.IsNullOrEmpty(phone))
                return Json(new AppResult
                {
                    Code = 500,
                    Message = "手机号码不能为空"
                });
            if (!_workContext.CurrentCustomer.IsRegistered())
                return Json(new AppResult
                {
                    Code = 999,
                    Message = "您还没有登录"
                });

            var ucMemberId = _hUCSdkHelper.GetMemberId(_workContext.CurrentCustomer);
            if (ucMemberId < 1)
                return Json(new AppResult
                {
                    Code = 999,
                    Message = "您还没有登录"
                });
            var memberResult = _hUCSdkHelper.Get().GetMemberAsync<UCMemberResult>(phone).Result;
            if (!memberResult.Success)
            {
                return Json(new AppResult
                {
                    Code = 500,
                    Message = "请检查输入的手机号码"
                });
            } 
            var toMemberId = memberResult.MemberId;
            if (toMemberId < 1)
                return Json(new AppResult
                {
                    Code = 500,
                    Message = "转账的用户不存在"
                });

            var sdk = _paySdkHelper.Get();
            var fromWalletResult = sdk.GetWallet(ucMemberId, walletType).Result;
            if (!fromWalletResult.Success)
            {
                return Json(new AppResult
                {
                    Code = 500,
                    Message = "无法获取转出钱包"
                });
            }
            if (fromWalletResult.Wallet.Balance < amount)
            {

                return Json(new AppResult
                {
                    Code = 500,
                    Message = "转出钱包余额不足"
                });
            }
            var toWalletResult = sdk.GetWallet(toMemberId, walletType).Result;

            bool hasWallet = toWalletResult.Success;
            if (!toWalletResult.Success && toWalletResult.Code.Equals("8007"))
            {
                var template = _productService.GetWalletTemplate(walletType);
                var createResult = sdk.CreateWalletAsync(toMemberId, walletType, template.Name, template.IconUrl).Result;
                hasWallet = createResult.Success;
            }
            if (!hasWallet)
            {
                return Json(new AppResult
                {
                    Code = 500,
                    Message = "转入钱包创建失败"
                });
            }
            toWalletResult = toWalletResult.Success ? toWalletResult : sdk.GetWallet(toMemberId, walletType).Result;
            if (!toWalletResult.Success)
            {
                return Json(new AppResult
                {
                    Code = 500,
                    Message = "无法获取转入钱包"
                });
            }
            var transferResult = sdk.TrasferWithId(new PayCenter.Sdk.Requests.TrasferWithIdRequest
            {
                Amount = amount,
                DistWalletId = toWalletResult.Wallet.WalletId,
                OutTradeNo = Guid.NewGuid().ToString("N"),
                SrcWalletId = fromWalletResult.Wallet.WalletId,
                Subject = "用户间转账"
            }).Result;
            if (!transferResult.Success)
            {
                return Json(new AppResult
                {
                    Code = 500,
                    Message = transferResult.Message
                });
            }
            return Json(new AppResult
            {

            });

        }
    }
}